﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;

namespace SalesSys.Comm.DAL
{
    /// <summary>
    /// 仓储标记接口
    /// </summary>
    public interface IRepository : IUnitOfWork
    {

    }

    /// <summary>
    ///     定义仓储模型中的数据标准操作
    /// </summary>
    /// <typeparam name="TEntity">动态实体类型</typeparam>
    public interface IRepository<TEntity> : IRepository where TEntity : IDbEntity
    {

        //IUnitContext UnitContext { get; set; }
        #region 属性

        /// <summary>
        ///     获取 当前实体的查询数据集
        /// </summary>
        IQueryable<TEntity> Entities { get; }

        #endregion

        #region 公共方法

         IQueryable<TEntity> EntitiesAsNoTracking(IQueryable<TEntity> entities = null);

        /// <summary>
        /// 通过条件查询,
        /// </summary>
        /// <param name="condition">简单条件组</param>
        /// <returns></returns>
          IQueryable<TEntity> QueryByWhere(IEnumerable<SqlItem> condition);
        /// <summary>
        /// 通过条件查询，并排序分页
        /// </summary>
        /// <param name="condition">简单条件组</param>
        /// <param name="pageIndex">页码，从1开始</param>
        /// <param name="pageSize">页大小，从1开始</param>
        /// <param name="sortConditions">排序条件,[名称：是否降序DESC(默认false即AES)]</param>
        /// <returns></returns>
          IQueryable<TEntity> QueryByWhere(IEnumerable<SqlItem> condition, int pageIndex, int pageSize,
         params  KeyValuePair<string, ListSortDirection>[] sortConditions);
        /// <summary>
        ///     插入实体记录
        /// </summary>
        /// <param name="entity"> 实体对象 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        int Insert(TEntity entity, bool isSave = true);

        /// <summary>
        ///     批量插入实体记录集合
        /// </summary>
        /// <param name="entities"> 实体记录集合 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        int Insert(IEnumerable<TEntity> entities, bool isSave = true);

        /// <summary>
        ///     删除指定编号的记录
        /// </summary>
        /// <param name="id"> 实体记录编号 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        int Delete(object id, bool isSave = true);

        /// <summary>
        /// 删除指定id的实体,联合主键
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="isSave"></param>
        /// <returns></returns>
        int Delete(object[] ids, bool isSave = true);
        /// <summary>
        ///     删除实体记录
        /// </summary>
        /// <param name="entity"> 实体对象 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        int Delete(TEntity entity, bool isSave = true);

        /// <summary>
        ///     删除实体记录集合
        /// </summary>
        /// <param name="entities"> 实体记录集合 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        int Delete(IEnumerable<TEntity> entities, bool isSave = true);

        /// <summary>
        ///     删除所有符合特定表达式的数据
        /// </summary>
        /// <param name="predicate"> 查询条件谓语表达式 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        int Delete(Expression<Func<TEntity, bool>> predicate, bool isSave = true);

        /// <summary>
        ///     更新实体记录
        /// </summary>
        /// <param name="entity"> 实体对象 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        int Update(TEntity entity, bool isSave = true);
        int Update(TEntity[] entitys, bool isSave = true);
        /// <summary>
        /// 使用附带新值的实体信息更新指定实体属性的值
        /// </summary>
        /// <param name="propertyExpression">属性表达式</param>
        /// <param name="isSave">是否执行保存</param>
        /// <param name="entity">附带新值的实体信息，必须包含主键</param>
        /// <returns>操作影响的行数</returns>
        //int Update(Expression<Func<TEntity, object>> propertyExpression, TEntity entity, bool isSave = true);

        /// <summary>
        ///     查找指定主键的实体记录
        /// </summary>
        /// <param name="key"> 指定主键 </param>
        /// <returns> 符合编号的记录，不存在返回null </returns>
        TEntity Find(params object[] keyValues);


        #endregion
    }

    /// <summary>
    /// 树型仓储接口
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    public interface ITreeRepository<TEntity> : IRepository<TEntity> where TEntity : ITreeEntity
    {

    }
}
